﻿using System.Threading;

namespace PeriodicalTaskDemo.Tasks
{
    /// <summary>
    /// 实际上这就是一个Action，无参数无返回值。
    /// </summary>
    public delegate void SimpleEventHandler();

    /// <summary>
    /// 用于处理周期性事务的类，包括启动、暂停、恢复和停止几种方法。具体参见文档：
    /// https://ai-cyber-security.feishu.cn/docx/OtD2dK0lHotM86xRX5XcziTtnTb
    /// </summary>
    public class PeriodicalTask
    {
        /// <summary>
        /// 周期的间隔，即两次执行的时间间隔，单位是毫秒，默认值是100ms。
        /// </summary>
        public int Interval { get; set; } = 100;

        /// <summary>
        /// 是否在运行中，对外只读属性。
        /// </summary>
        public bool IsRunning { get; private set; } = false;

        // 主要线程
        private Thread thread;
        // 线程是否在暂停状态。
        bool isPaused = false;

        public event SimpleEventHandler BeforeStart;
        public event SimpleEventHandler AfterStop;
        public event SimpleEventHandler Processing;

        /// <summary>
        /// 默认构造函数，啥也不做。
        /// </summary>
        public PeriodicalTask() { }

        /// <summary>
        /// 指定周期间隔，其他啥也不做。
        /// </summary>
        /// <param name="interval">周期间隔。</param>
        public PeriodicalTask(int interval) { Interval = interval; }



        /// <summary>
        /// 任务启动前调用。
        /// </summary>
        public virtual void OnStart() { }

        /// <summary>
        /// 任务停止后调用。
        /// </summary>
        public virtual void OnStop() { }

        /// <summary>
        /// 周期性任务。
        /// </summary>
        public virtual void DoWork() { }


        void process()
        {
            BeforeStart?.Invoke();
            OnStart();

            while (IsRunning)
            {
                if (isPaused)
                {
                    Thread.Sleep(1);
                    continue;
                }

                Processing?.Invoke();
                DoWork();
                Thread.Sleep(Interval);
            }
            OnStop();
            AfterStop?.Invoke();
        }

        /// <summary>
        /// 启动线程，如果为空或不是未启动，都会新建线程和任务。
        /// </summary>
        public void Start()
        {
            if (thread == null || thread.ThreadState != ThreadState.Unstarted)
            {
                thread = new Thread(new ThreadStart(process));
                thread.IsBackground = true;
            }
            IsRunning = true;
            isPaused = false;
            OnStart();
            thread.Start();
        }

        /// <summary>
        /// 结束线程，实际上是设置IsRunning为false即可。
        /// </summary>
        public void Stop()
        {
            IsRunning = false;
            isPaused = true;
            OnStop();
        }

        /// <summary>
        /// 在线程执行中临时暂停执行任务。
        /// </summary>
        public void Pause()
        {
            if (IsRunning)
            {
                isPaused = true;
            }
        }

        /// <summary>
        /// 恢复已经暂停的任务，只有牌暂停中的任务可以恢复。
        /// </summary>
        public void Resume()
        {
            if (IsRunning && isPaused)
            {
                isPaused = false;
            }
        }
    }
}
